最近在前端持续集成上面遇到一个问题,在百度上查了无数资料,无解!!也可能是我搜索姿势不对… -_-
但是当我尝试在google上搜索时,很快得到了答案。
写这段话的目的不是为了黑百度,扬谷歌,望勿借题发挥。至于我的目的,你们自行脑补。😄
前端持续集成,目前流行的平台 circleCI、travis ci等,两者的区别不多介绍,大家可以自行搜索。
CI的配置也不多做介绍,有兴趣的可以去他们的官网。
我用CI做了个发布demo的测试,主要流程是当我提交代码到github仓库时,CI会自动拉取代码或者说clone最新代码到虚拟机上,然后CI会找到仓库里的.yml(CI的配置文件),并依次执行配置文件里面的预先定义好的代码。
配置文件里面的代码流程是利用webpack编译一个静态的demo出来,编译输出地址为.examples
,然后将examples里面的静态文件推送到gh-pages分支。
代码如下:
注意:
${...}
里面的内容为CI变量,这个可以在CI平台的设置里面预先定义好,这里不过多讨论。
为什么要在用变量,而不直接写在配置文件里?如果是私有仓库,则可以这么做;如果是公开仓库,那你的密码会被所有人看见。
1 | git remote rm origin |
执行git remote rm origin
的原因是CI在clone项目的时候使用的是如下命令:
1 | git clone --depth=50 --branch=master https://github.com/${username}/${repositoryName}.git ${username}/${repositoryName} |
可以清楚地看到这只是一个普通的clone仓库代码,里面没有包含用户名和密码,这样就不能直接push代码到github仓库了,所以要做一下修改。
因为这些流程是在CI的虚拟机里面完成的,我们不能也无法在push代码的时候输入用户名和密码,所以要把仓库的用户名(username)和密码(password)写到仓库地址中去。
如下:
1 | git remote add orgin "https://${username}:${password}@github.com/${username}/${repositoryName}.git" |
这样我们就可以把webpack编译好的demo的静态文件后直接push到gh-pages分支了。
当然还有另外的解决方案,如:
- 在虚拟机里面设置全局的用户名和密码。
- 用
token
来代替password
代替,这样自己的密码被保护得更好,只需一个token就行。
1 | yarn webpack --config build/webpack.config.demo |
这句代码就是用webpack打包静态文件,输出到./examples
文件夹下。
1 | git subtree push -P examples github gh-pages |
这句代码是把examples文件夹下的demo静态文件push到gh-pages分支。
执行到这里,问题来了,CI虚拟机报错:
1 | ! [rejected] ******299ab2694e13f437654jb8561c98****** -> gh-pages (fetch first) |
依照问题的提示,在push
代码之前执行git pull
。
但是这样做又会包另外一个错误:
1 | ! [rejected] ******299ab2694e13f437654jb8561c98****** -> gh-pages (non-fast-forward) |
最终换了下思路,强制推送新的静态文件到gh-pages分支
但是我使用的是git subtree,它没有强制推送 –force 这个选项,最终在google里搜索得到如下方法:
1 | git push github `git subtree split --prefix examples master`:gh-pages --force |
然后提交代码到github,CI自动拉去最新代码及配置文件开始跑虚拟机,等待…success!
最终跑通的流程代码如下:
1 | git remote rm origin |